asynchroni volani udalosti z COM objektu (Automation objektu)
Otázka od: Karel Kimes
18. 9. 2002 12:07
ahoj,
- mam vytvoreny COM objekt (Automation objekt) TTest s podporou pro volani
udalosti
- objekt ma metodu Go
- tato metoda VYTVORI novou instanci vlakna (potomek TThread) a teto
instanci je v v jehoz metode execute se, z duvodu testu, ceka 5s a potom
se vyvola udalost OnEvent
ALE ono to NEFUNGUJE! Je to proto, ze tu udalost volam z jinyho vlakna? Jde
tady o chybu, z duvodu, ze udalost volam z jinyho apartmentu?
Jde mne o toto: zavolat metodu COM objektu, ktera v COM objektu spusti
nejaky asynchroni algoritmus a IHNED se vrati. Jakmile asynchroni alg.
napr. vypocita vysledek, chcu se o tom dozvedet, tzn. vyvolat udalost pro
klienta. Tak jak to delam ted to nefunguje.
castecna implementace kodu, avsak pro nastineni situace dostacujici:
TTestThread = class(TThread) // **** moje testovaci vlakno
private
FEvents : ITestEvents;
protected
procedure Execute; override;
public
constructor Create(Events : ITestEvents);
end;
TTest = class(TAutoObject, IConnectionPointContainer, ITest)
private
{ Private declarations }
FConnectionPoints: TConnectionPoints;
FConnectionPoint: TConnectionPoint;
FEvents: ITestEvents;
{ note: FEvents maintains a *single* event sink. For access to more
than one event sink, use FConnectionPoint.SinkList, and iterate
through the list of sinks. }
public
procedure Initialize; override;
protected
{ Protected declarations }
property ConnectionPoints: TConnectionPoints read FConnectionPoints
implements IConnectionPointContainer;
procedure EventSinkChanged(const EventSink: IUnknown); override;
procedure Go; safecall; // **** TOTO je moje metoda - osatatni casti
tohotobjektu vytvoril Wizard (DAX)
end;
implementation
constructor TTestThread.Create(Events : ITestEvents);
begin
inherited Create(true);
FreeOnTerminate := true;
FEvents := Events;
Resume;
end;
procedure TTestThread.Execute;
begin
Sleep(5000); // vlakno ceka 5s
FEvents.OnEvent; // a potom vola udalost OnEvent (ktera je
implementovana v klintovi) - ALE ONO TO NEJEDE
end;
procedure TTest.Go;
begin
TTestThread.Create(FEvents); // spustim vlakno a IHNED se vratim
end;
kchodl
WinXP, D6PRO UPDATE PACK 2
Odpovedá: Malecek Ondrej
18. 9. 2002 12:38
Ahoj,
krome predavani instanci COM objektu mezi procesy se mezi thready musi vzdy
marshalovat. K plne spokojenosti pouzivam helpery:
CoMarshalInterThreadInterfaceInStream
a
CoGetInterfaceAndReleaseStream
O
> -----Původní zpráva-----
> ahoj,
> - mam vytvoreny COM objekt (Automation objekt) TTest s podporou
> pro volani
> udalosti
> - objekt ma metodu Go
> - tato metoda VYTVORI novou instanci vlakna (potomek TThread) a teto
> instanci je v v jehoz metode execute se, z duvodu testu, ceka 5s a potom
> se vyvola udalost OnEvent
>
> ALE ono to NEFUNGUJE! Je to proto, ze tu udalost volam z jinyho
> vlakna? Jde
> tady o chybu, z duvodu, ze udalost volam z jinyho apartmentu?
>
>
> Jde mne o toto: zavolat metodu COM objektu, ktera v COM objektu spusti
> nejaky asynchroni algoritmus a IHNED se vrati. Jakmile asynchroni alg.
> napr. vypocita vysledek, chcu se o tom dozvedet, tzn. vyvolat udalost pro
> klienta. Tak jak to delam ted to nefunguje.